package cur.nature.framework.mvc.util;

import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;
import org.springframework.scheduling.support.CronExpression;

import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Optional;

import static com.cronutils.model.CronType.QUARTZ;

public class CronUtil {

    final static CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
    final static CronParser parser = new CronParser(cronDefinition);
    public static CronDefinition buildCronDefinition(){
//        CronDefinition cronDefinition = CronDefinitionBuilder.defineCron()
//                .withSeconds().and()
//                .withMinutes().and()
//                .withHours().and()
//                .withDayOfMonth()
//                .supportsHash().supportsL().supportsW().and()
//                .withMonth().and()
//                .withDayOfWeek()
//                .withIntMapping(7, 0) //we support non-standard non-zero-based numbers!
//                .supportsHash().supportsL().supportsW().and()
//                .withYear().optional().and()
//                .instance();
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
        return cronDefinition;
    }

    public static ZonedDateTime getNextRunTime(final String cron, final ZonedDateTime curDateTime) {

        ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(cron));
        // 获取下一次执行日期
//        ZonedDateTime now = ZonedDateTime.now();
        Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(curDateTime);
        return nextExecution.get();
    }

    public static boolean isValidExpression(String expression) {
        try {
            CronExpression.parse(expression);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // 计算时间间隔， 以秒为单位返回
    public static Long calcInterval(final String cron, final ZonedDateTime now) {
        final ZonedDateTime startTime = getNextRunTime(cron, now);
        final ZonedDateTime endTime = getNextRunTime(cron, startTime);
        long betweenSeconds = ChronoUnit.SECONDS.between(startTime, endTime);

        return betweenSeconds;
    }

}
